using System.Runtime.CompilerServices;

namespace Sage.Data.Extensions
{
    /// <summary>
    /// 提供整型(int)类型的扩展方法，用于数值转换、格式化等常用操作。
    /// </summary>
    /// <remarks>
    /// 此类包含针对<see cref="int"/>类型的扩展方法，使整型数值相关操作更加简洁和直观。
    /// 所有方法都是线程安全的，可以在多线程环境中使用。
    /// </remarks>
    public static class IntExtensions
    {
        #region 数值判断

        /// <summary>
        /// 判断数值是否在指定范围内（包含边界）。
        /// </summary>
        /// <param name="value">要判断的数值。</param>
        /// <param name="min">最小值（包含）。</param>
        /// <param name="max">最大值（包含）。</param>
        /// <returns>如果数值在范围内则返回true，否则返回false。</returns>
        /// <example>
        /// <code>
        /// int age = 25;
        /// bool isAdult = age.Between(18, 100); // 返回 true
        /// 
        /// int score = 85;
        /// bool isPassing = score.Between(60, 100); // 返回 true
        /// 
        /// // 验证HTTP状态码
        /// int statusCode = 404;
        /// bool isClientError = statusCode.Between(400, 499); // 返回 true
        /// </code>
        /// </example>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static bool Between(this int value, int min, int max)
        {
            return value >= min && value <= max;
        }

        /// <summary>
        /// 判断是否为偶数。
        /// </summary>
        /// <param name="value">要判断的数值。</param>
        /// <returns>如果是偶数则返回true，否则返回false。</returns>
        /// <example>
        /// <code>
        /// int number = 42;
        /// bool even = number.IsEven(); // 返回 true
        /// 
        /// // 判断页码奇偶性
        /// int pageNumber = 3;
        /// if (pageNumber.IsOdd()) 
        /// {
        ///     // 奇数页处理
        /// }
        /// </code>
        /// </example>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static bool IsEven(this int value) => value % 2 == 0;

        /// <summary>
        /// 判断是否为奇数。
        /// </summary>
        /// <param name="value">要判断的数值。</param>
        /// <returns>如果是奇数则返回true，否则返回false。</returns>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static bool IsOdd(this int value) => value % 2 != 0;

        /// <summary>
        /// 判断是否为质数（素数）。
        /// </summary>
        /// <param name="value">要判断的整数。</param>
        /// <returns>如果是质数则返回true，否则返回false。</returns>
        /// <example>
        /// <code>
        /// bool isPrime1 = 7.IsPrime(); // 返回 true
        /// bool isPrime2 = 8.IsPrime(); // 返回 false
        /// bool isPrime3 = 2.IsPrime(); // 返回 true（最小质数）
        /// bool isPrime4 = 1.IsPrime(); // 返回 false（1不是质数）
        /// 
        /// // 找出范围内的所有质数
        /// var primes = Enumerable.Range(2, 100).Where(n => n.IsPrime()).ToList();
        /// 
        /// // 验证加密算法中的质数
        /// int p = 1009;
        /// if (p.IsPrime()) {
        ///     Console.WriteLine("适合用作RSA密钥的质数");
        /// }
        /// </code>
        /// </example>
        /// <remarks>
        /// 使用试除法判断质数，对于大数可能性能较慢。
        /// 1和负数不被认为是质数。
        /// 2是唯一的偶数质数。
        /// 常用于数学计算、密码学、算法题等场景。
        /// </remarks>
        public static bool IsPrime(this int value)
        {
            if (value < 2) return false;
            if (value == 2) return true;
            if (value % 2 == 0) return false;

            var sqrt = (int)Math.Sqrt(value);
            for (int i = 3; i <= sqrt; i += 2)
            {
                if (value % i == 0) return false;
            }
            return true;
        }

        /// <summary>
        /// 判断数值是否为正数（大于0）。
        /// </summary>
        /// <param name="value">要判断的数值。</param>
        /// <returns>如果大于0则返回true。</returns>
        /// <example>
        /// <code>
        /// int balance = 1000;
        /// if (balance.IsPositive())
        /// {
        ///     Console.WriteLine("账户有余额");
        /// }
        /// </code>
        /// </example>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static bool IsPositive(this int value) => value > 0;

        /// <summary>
        /// 判断数值是否为负数（小于0）。
        /// </summary>
        /// <param name="value">要判断的数值。</param>
        /// <returns>如果小于0则返回true。</returns>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static bool IsNegative(this int value) => value < 0;

        /// <summary>
        /// 判断数值是否为0。
        /// </summary>
        /// <param name="value">要判断的数值。</param>
        /// <returns>如果等于0则返回true。</returns>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static bool IsZero(this int value) => value == 0;

        /// <summary>
        /// 获取数值的符号。
        /// </summary>
        /// <param name="value">要判断的数值。</param>
        /// <returns>正数返回1，负数返回-1，零返回0。</returns>
        /// <example>
        /// <code>
        /// int positive = 100;
        /// int sign1 = positive.GetSign(); // 返回 1
        /// 
        /// int negative = -50;
        /// int sign2 = negative.GetSign(); // 返回 -1
        /// 
        /// int zero = 0;
        /// int sign3 = zero.GetSign(); // 返回 0
        /// </code>
        /// </example>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static int GetSign(this int value) => Math.Sign(value);

        #endregion

        #region 格式化方法

        /// <summary>
        /// 将整数转换为二进制字符串。
        /// </summary>
        /// <param name="value">要转换的整数。</param>
        /// <returns>二进制字符串表示。</returns>
        /// <example>
        /// <code>
        /// int number = 10;
        /// string binary = number.ToBinary(); // 返回 "1010"
        /// 
        /// int flags = 7;
        /// string binaryFlags = flags.ToBinary(); // 返回 "111"
        /// </code>
        /// </example>
        public static string ToBinary(this int value)
        {
            return Convert.ToString(value, 2);
        }

        /// <summary>
        /// 将整数转换为十六进制字符串。
        /// </summary>
        /// <param name="value">要转换的整数。</param>
        /// <param name="uppercase">是否使用大写字母，默认为true。</param>
        /// <returns>十六进制字符串表示。</returns>
        /// <example>
        /// <code>
        /// int color = 255;
        /// string hex = color.ToHexString(); // 返回 "FF"
        /// string hexLower = color.ToHexString(false); // 返回 "ff"
        /// 
        /// // RGB颜色值
        /// int red = 255, green = 128, blue = 0;
        /// string colorHex = $"#{red.ToHexString()}{green.ToHexString()}{blue.ToHexString()}"; // "#FF8000"
        /// </code>
        /// </example>
        public static string ToHexString(this int value, bool uppercase = true)
        {
            string hex = Convert.ToString(value, 16);
            return uppercase ? hex.ToUpperInvariant() : hex;
        }

        /// <summary>
        /// 将整数格式化为货币字符串（人民币）。
        /// </summary>
        /// <param name="value">要格式化的金额（分为单位）。</param>
        /// <returns>格式化后的货币字符串。</returns>
        /// <example>
        /// <code>
        /// int priceInCents = 12345; // 123.45元
        /// string price = priceInCents.ToCurrencyString(); // 返回 "¥123.45"
        /// 
        /// int amount = 100000; // 1000.00元
        /// string formatted = amount.ToCurrencyString(); // 返回 "¥1,000.00"
        /// </code>
        /// </example>
        public static string ToCurrencyString(this int value)
        {
            decimal amount = value / 100m;
            return amount.ToString("C", new System.Globalization.CultureInfo("zh-CN"));
        }

        /// <summary>
        /// 将整数转换为中文数字字符串。
        /// </summary>
        /// <param name="value">要转换的整数，支持-99999到99999范围。</param>
        /// <returns>中文数字字符串。超出支持范围则返回原数字的字符串形式。</returns>
        /// <example>
        /// <code>
        /// int num1 = 123;
        /// string chinese1 = num1.ToChineseString(); // 返回 "一百二十三"
        /// 
        /// int num2 = 1001;
        /// string chinese2 = num2.ToChineseString(); // 返回 "一千零一"
        /// 
        /// int num3 = 10;
        /// string chinese3 = num3.ToChineseString(); // 返回 "十"
        /// 
        /// int num4 = -15;
        /// string chinese4 = num4.ToChineseString(); // 返回 "负十五"
        /// 
        /// // 用于显示楼层、年龄等
        /// int floor = 8;
        /// Console.WriteLine($"{floor.ToChineseString()}楼"); // "八楼"
        /// </code>
        /// </example>
        /// <remarks>
        /// 支持负数转换，会在前面加"负"字。
        /// 对于10-19的数字，会省略"一"，如"十五"而不是"一十五"。
        /// 适用于显示楼层、年龄、数量等需要中文数字的场景。
        /// </remarks>
        public static string ToChineseString(this int value)
        {
            if (value < -99999 || value > 99999)
                return value.ToString();

            if (value == 0) return "零";

            bool isNegative = value < 0;
            value = Math.Abs(value);

            string[] digits = ["", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
            string[] units = ["", "十", "百", "千", "万"];

            string result = "";
            string numStr = value.ToString();
            int length = numStr.Length;
            bool needZero = false;

            for (int i = 0; i < length; i++)
            {
                int digit = int.Parse(numStr[i].ToString());
                int position = length - i - 1;

                if (digit != 0)
                {
                    if (needZero)
                    {
                        result += "零";
                        needZero = false;
                    }
                    result += digits[digit] + units[position];
                }
                else
                {
                    if (result.Length > 0 && position > 0)
                    {
                        needZero = true;
                    }
                }
            }

            // 处理特殊情况：十几的数字
            if (value >= 10 && value < 20)
            {
                result = result.TrimStart('一');
            }

            return (isNegative ? "负" : "") + result;
        }

        /// <summary>
        /// 将整数格式化为带千分位分隔符的字符串。
        /// </summary>
        /// <param name="value">要格式化的整数。</param>
        /// <param name="separator">千分位分隔符，默认为逗号。</param>
        /// <returns>格式化后的字符串。</returns>
        /// <example>
        /// <code>
        /// int population = 1234567;
        /// string formatted = population.ToThousandsSeparator(); // 返回 "1,234,567"
        /// string formatted2 = population.ToThousandsSeparator(" "); // 返回 "1 234 567"
        /// 
        /// // 显示统计数据
        /// int userCount = 523456;
        /// Console.WriteLine($"总用户数：{userCount.ToThousandsSeparator()}");
        /// </code>
        /// </example>
        public static string ToThousandsSeparator(this int value, string separator = ",")
        {
            return value.ToString("#,0").Replace(",", separator);
        }

        #endregion

        #region 类型转换

        /// <summary>
        /// 将整型转换为长整型。
        /// </summary>
        /// <param name="value">要转换的整型值。</param>
        /// <returns>转换后的长整型值。</returns>
        /// <example>
        /// <code>
        /// int id = 12345;
        /// long longId = id.ToLong(); // 返回 12345L
        /// </code>
        /// </example>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static long ToLong(this int value) => value;

        /// <summary>
        /// 将整型转换为双精度浮点数。
        /// </summary>
        /// <param name="value">要转换的整型值。</param>
        /// <returns>转换后的双精度浮点数。</returns>
        /// <example>
        /// <code>
        /// int score = 85;
        /// double percent = score.ToDouble() / 100; // 计算百分比
        /// </code>
        /// </example>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static double ToDouble(this int value) => value;

        /// <summary>
        /// 将整型转换为decimal类型。
        /// </summary>
        /// <param name="value">要转换的整型值。</param>
        /// <returns>转换后的decimal值。</returns>
        /// <example>
        /// <code>
        /// int cents = 12345; // 分
        /// decimal yuan = cents.ToDecimal() / 100; // 转换为元
        /// </code>
        /// </example>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static decimal ToDecimal(this int value) => value;

        /// <summary>
        /// 将整型安全转换为短整型，超出范围返回null。
        /// </summary>
        /// <param name="value">要转换的整型值。</param>
        /// <returns>转换成功返回短整型值，超出范围返回null。</returns>
        /// <example>
        /// <code>
        /// int small = 100;
        /// short? result1 = small.ToShortOrNull(); // 返回 100
        /// 
        /// int large = 100000;
        /// short? result2 = large.ToShortOrNull(); // 返回 null
        /// </code>
        /// </example>
        public static short? ToShortOrNull(this int value)
        {
            if (value > short.MaxValue || value < short.MinValue)
                return null;
            return (short)value;
        }

        /// <summary>
        /// 将整型安全转换为字节，超出范围返回null。
        /// </summary>
        /// <param name="value">要转换的整型值。</param>
        /// <returns>转换成功返回字节值，超出范围返回null。</returns>
        /// <example>
        /// <code>
        /// int age = 25;
        /// byte? result1 = age.ToByteOrNull(); // 返回 25
        /// 
        /// int large = 300;
        /// byte? result2 = large.ToByteOrNull(); // 返回 null
        /// </code>
        /// </example>
        public static byte? ToByteOrNull(this int value)
        {
            if (value > byte.MaxValue || value < byte.MinValue)
                return null;
            return (byte)value;
        }

        #endregion

        #region 时间相关

        /// <summary>
        /// 将整数转换为TimeSpan（以秒为单位）。
        /// </summary>
        /// <param name="seconds">秒数。</param>
        /// <returns>对应的TimeSpan对象。</returns>
        /// <example>
        /// <code>
        /// int timeout = 30; // 30秒
        /// TimeSpan timeoutSpan = timeout.Seconds();
        /// 
        /// // 设置缓存过期时间
        /// int cacheMinutes = 15;
        /// TimeSpan expiry = cacheMinutes.Minutes();
        /// </code>
        /// </example>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static TimeSpan Seconds(this int seconds) => TimeSpan.FromSeconds(seconds);

        /// <summary>
        /// 将整数转换为TimeSpan（以分钟为单位）。
        /// </summary>
        /// <param name="minutes">分钟数。</param>
        /// <returns>对应的TimeSpan对象。</returns>
        /// <example>
        /// <code>
        /// var timeout = 30.Minutes(); // 30分钟
        /// await Task.Delay(5.Minutes()); // 延迟5分钟
        /// </code>
        /// </example>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static TimeSpan Minutes(this int minutes) => TimeSpan.FromMinutes(minutes);

        /// <summary>
        /// 将整数转换为TimeSpan（以小时为单位）。
        /// </summary>
        /// <param name="hours">小时数。</param>
        /// <returns>对应的TimeSpan对象。</returns>
        /// <example>
        /// <code>
        /// var workTime = 8.Hours(); // 8小时工作时间
        /// var delay = 2.Hours(); // 2小时延迟
        /// </code>
        /// </example>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static TimeSpan Hours(this int hours) => TimeSpan.FromHours(hours);

        /// <summary>
        /// 将整数转换为TimeSpan（以天为单位）。
        /// </summary>
        /// <param name="days">天数。</param>
        /// <returns>对应的TimeSpan对象。</returns>
        /// <example>
        /// <code>
        /// var expiry = DateTime.Now.Add(30.Days()); // 30天后
        /// var cacheTime = 7.Days(); // 7天的时间间隔
        /// </code>
        /// </example>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static TimeSpan Days(this int days) => TimeSpan.FromDays(days);

        /// <summary>
        /// 将整数转换为TimeSpan（以毫秒为单位）。
        /// </summary>
        /// <param name="milliseconds">毫秒数。</param>
        /// <returns>对应的TimeSpan对象。</returns>
        /// <example>
        /// <code>
        /// var delay = 500.Milliseconds(); // 500毫秒
        /// await Task.Delay(100.Milliseconds());
        /// </code>
        /// </example>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static TimeSpan Milliseconds(this int milliseconds) => TimeSpan.FromMilliseconds(milliseconds);

        #endregion

        #region 数值操作

        /// <summary>
        /// 确保数值在指定范围内，超出范围则返回边界值。
        /// </summary>
        /// <param name="value">要限制的数值。</param>
        /// <param name="min">最小值。</param>
        /// <param name="max">最大值。</param>
        /// <returns>限制在范围内的数值。</returns>
        /// <example>
        /// <code>
        /// int score = 150;
        /// int clampedScore = score.Clamp(0, 100); // 返回 100
        /// 
        /// int volume = -5;
        /// int safeVolume = volume.Clamp(0, 100); // 返回 0
        /// 
        /// // 限制分页参数
        /// int pageSize = 1000;
        /// int safePageSize = pageSize.Clamp(1, 50); // 返回 50
        /// </code>
        /// </example>
        public static int Clamp(this int value, int min, int max)
        {
            if (value < min) return min;
            if (value > max) return max;
            return value;
        }

        /// <summary>
        /// 获取数值的绝对值。
        /// </summary>
        /// <param name="value">要处理的数值。</param>
        /// <returns>绝对值。</returns>
        /// <example>
        /// <code>
        /// int negative = -100;
        /// int positive = negative.Abs(); // 返回 100
        /// </code>
        /// </example>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static int Abs(this int value) => Math.Abs(value);

        /// <summary>
        /// 返回当前值和另一个值中的较大值。
        /// </summary>
        /// <param name="value">当前值。</param>
        /// <param name="other">比较值。</param>
        /// <returns>两者中的较大值。</returns>
        /// <example>
        /// <code>
        /// int score = 85;
        /// int minScore = score.Max(60); // 返回 85
        /// </code>
        /// </example>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static int Max(this int value, int other) => Math.Max(value, other);

        /// <summary>
        /// 返回当前值和另一个值中的较小值。
        /// </summary>
        /// <param name="value">当前值。</param>
        /// <param name="other">比较值。</param>
        /// <returns>两者中的较小值。</returns>
        /// <example>
        /// <code>
        /// int remaining = 1000;
        /// int pageSize = remaining.Min(100); // 最多取100条
        /// </code>
        /// </example>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static int Min(this int value, int other) => Math.Min(value, other);

        /// <summary>
        /// 计算整数的阶乘。
        /// </summary>
        /// <param name="value">要计算阶乘的整数，必须为非负数。</param>
        /// <returns>阶乘结果。如果输入为负数则返回0。</returns>
        /// <example>
        /// <code>
        /// int result1 = 5.Factorial(); // 返回 120 (5! = 5×4×3×2×1)
        /// int result2 = 0.Factorial(); // 返回 1 (0! = 1)
        /// int result3 = 1.Factorial(); // 返回 1 (1! = 1)
        /// 
        /// // 计算排列组合
        /// int n = 8, r = 3;
        /// int permutation = n.Factorial() / (n - r).Factorial(); // P(8,3)
        /// 
        /// // 数学计算
        /// int factorial10 = 10.Factorial(); // 3628800
        /// </code>
        /// </example>
        /// <remarks>
        /// 阶乘增长极快，建议只对较小的数字使用，避免整数溢出。
        /// 对于大数阶乘计算，建议使用BigInteger或double类型。
        /// 负数的阶乘在数学上未定义，此方法返回0。
        /// 常用于数学计算、排列组合、概率统计等场景。
        /// </remarks>
        public static long Factorial(this int value)
        {
            if (value < 0) return 0;
            if (value <= 1) return 1;

            long result = 1;
            for (int i = 2; i <= value; i++)
            {
                result *= i;
            }
            return result;
        }

        /// <summary>
        /// 将数值向上取整到指定倍数。
        /// </summary>
        /// <param name="value">要处理的数值。</param>
        /// <param name="multiple">倍数（必须大于0）。</param>
        /// <returns>向上取整后的值。</returns>
        /// <exception cref="ArgumentException">当倍数小于等于0时抛出。</exception>
        /// <example>
        /// <code>
        /// int size = 1234;
        /// int rounded = size.RoundUpToMultiple(100); // 返回 1300
        /// 
        /// // 内存对齐
        /// int memSize = 1050;
        /// int aligned = memSize.RoundUpToMultiple(1024); // 对齐到1024字节
        /// 
        /// // 分页计算
        /// int totalItems = 95;
        /// int pageSize = 10;
        /// int totalPages = totalItems.RoundUpToMultiple(pageSize) / pageSize; // 10页
        /// </code>
        /// </example>
        public static int RoundUpToMultiple(this int value, int multiple)
        {
            if (multiple <= 0) throw new ArgumentException("倍数必须大于0", nameof(multiple));

            return ((value + multiple - 1) / multiple) * multiple;
        }

        /// <summary>
        /// 将数值向下取整到指定倍数。
        /// </summary>
        /// <param name="value">要处理的数值。</param>
        /// <param name="multiple">倍数（必须大于0）。</param>
        /// <returns>向下取整后的值。</returns>
        /// <exception cref="ArgumentException">当倍数小于等于0时抛出。</exception>
        /// <example>
        /// <code>
        /// int size = 1234;
        /// int rounded = size.RoundDownToMultiple(100); // 返回 1200
        /// </code>
        /// </example>
        public static int RoundDownToMultiple(this int value, int multiple)
        {
            if (multiple <= 0) throw new ArgumentException("倍数必须大于0", nameof(multiple));

            return (value / multiple) * multiple;
        }

        /// <summary>
        /// 将数值按比例缩放到新的范围。
        /// </summary>
        /// <param name="value">原始值。</param>
        /// <param name="fromMin">原始范围最小值。</param>
        /// <param name="fromMax">原始范围最大值。</param>
        /// <param name="toMin">目标范围最小值。</param>
        /// <param name="toMax">目标范围最大值。</param>
        /// <returns>缩放后的值。</returns>
        /// <example>
        /// <code>
        /// // 将0-100的分数转换为0-5星级
        /// int score = 85;
        /// int stars = score.Scale(0, 100, 0, 5); // 返回 4
        /// 
        /// // 将传感器读数(0-1023)转换为百分比(0-100)
        /// int sensorValue = 512;
        /// int percentage = sensorValue.Scale(0, 1023, 0, 100); // 返回 50
        /// 
        /// // 音量调节
        /// int volume = 75; // 0-100
        /// int amplifierLevel = volume.Scale(0, 100, 0, 255); // 转换为放大器级别
        /// </code>
        /// </example>
        public static int Scale(this int value, int fromMin, int fromMax, int toMin, int toMax)
        {
            return (value - fromMin) * (toMax - toMin) / (fromMax - fromMin) + toMin;
        }

        #endregion

        #region 实用工具方法

        /// <summary>
        /// 计算数值的位数（不包括负号）。
        /// </summary>
        /// <param name="value">要计算的数值。</param>
        /// <returns>位数。</returns>
        /// <example>
        /// <code>
        /// int number = 12345;
        /// int digits = number.DigitCount(); // 返回 5
        /// 
        /// int negative = -9999;
        /// int digits2 = negative.DigitCount(); // 返回 4
        /// 
        /// int zero = 0;
        /// int digits3 = zero.DigitCount(); // 返回 1
        /// </code>
        /// </example>
        public static int DigitCount(this int value)
        {
            if (value == 0) return 1;
            return (int)Math.Floor(Math.Log10(Math.Abs(value))) + 1;
        }

        /// <summary>
        /// 重复执行指定操作。
        /// </summary>
        /// <param name="times">重复次数。</param>
        /// <param name="action">要执行的操作，参数为当前索引（从0开始）。</param>
        /// <exception cref="ArgumentNullException">当action为null时抛出。</exception>
        /// <example>
        /// <code>
        /// // 创建测试数据
        /// var items = new List&lt;string&gt;();
        /// 5.Times(i => items.Add($"Item {i + 1}"));
        /// 
        /// // 重复输出
        /// 3.Times(i => Console.WriteLine($"第 {i + 1} 次执行"));
        /// 
        /// // 批量操作
        /// 10.Times(i => ProcessBatch(i));
        /// </code>
        /// </example>
        /// <remarks>
        /// 如果次数小于等于0，则不执行任何操作。
        /// 适用于循环创建数据、批量处理、测试场景等。
        /// </remarks>
        public static void Times(this int times, Action<int> action)
        {
            ArgumentNullException.ThrowIfNull(action);
            if (times <= 0) return;

            for (int i = 0; i < times; i++)
            {
                action(i);
            }
        }

        /// <summary>
        /// 生成从0到指定数值的整数序列（不包含上限）。
        /// </summary>
        /// <param name="count">序列长度。</param>
        /// <returns>整数序列。</returns>
        /// <example>
        /// <code>
        /// var numbers = 5.ToRange().ToList(); // [0, 1, 2, 3, 4]
        /// 
        /// // 创建索引数组
        /// var indices = 10.ToRange().ToArray();
        /// 
        /// // 配合LINQ使用
        /// var evenNumbers = 10.ToRange().Where(x => x.IsEven()).ToList();
        /// </code>
        /// </example>
        public static IEnumerable<int> ToRange(this int count)
        {
            if (count <= 0) yield break;

            for (int i = 0; i < count; i++)
            {
                yield return i;
            }
        }

        /// <summary>
        /// 生成从当前值到目标值的整数序列（包含边界）。
        /// </summary>
        /// <param name="start">起始值。</param>
        /// <param name="end">结束值。</param>
        /// <returns>整数序列。</returns>
        /// <example>
        /// <code>
        /// // 生成1到10的序列
        /// var numbers = 1.To(10).ToList(); // [1, 2, 3, ..., 10]
        /// 
        /// // 倒序也支持
        /// var reverse = 10.To(1).ToList(); // [10, 9, 8, ..., 1]
        /// 
        /// // LINQ结合使用
        /// var primes = 2.To(100).Where(n => n.IsPrime()).ToList();
        /// 
        /// // 遍历年份范围
        /// foreach (var year in 2020.To(2024))
        /// {
        ///     Console.WriteLine(year);
        /// }
        /// </code>
        /// </example>
        public static IEnumerable<int> To(this int start, int end)
        {
            if (start <= end)
            {
                for (int i = start; i <= end; i++)
                    yield return i;
            }
            else
            {
                for (int i = start; i >= end; i--)
                    yield return i;
            }
        }

        /// <summary>
        /// 生成从当前值开始的指定步长的整数序列。
        /// </summary>
        /// <param name="start">起始值。</param>
        /// <param name="end">结束值。</param>
        /// <param name="step">步长（必须大于0）。</param>
        /// <returns>整数序列。</returns>
        /// <exception cref="ArgumentException">当步长小于等于0时抛出。</exception>
        /// <example>
        /// <code>
        /// // 生成偶数序列
        /// var evens = 0.Step(10, 2).ToList(); // [0, 2, 4, 6, 8, 10]
        /// 
        /// // 生成每5个的序列
        /// var fives = 0.Step(50, 5).ToList(); // [0, 5, 10, 15, ..., 50]
        /// 
        /// // 倒序步长
        /// var countdown = 100.Step(0, 10).ToList(); // [100, 90, 80, ..., 0]
        /// </code>
        /// </example>
        public static IEnumerable<int> Step(this int start, int end, int step)
        {
            if (step <= 0) throw new ArgumentException("步长必须大于0", nameof(step));

            if (start <= end)
            {
                for (int i = start; i <= end; i += step)
                    yield return i;
            }
            else
            {
                for (int i = start; i >= end; i -= step)
                    yield return i;
            }
        }

        #endregion
    }
}
